package org.andromeo;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Vector;

import javax.xml.parsers.ParserConfigurationException;

import org.andromeo.connectionapi.LoginProcessor;
import org.xml.sax.SAXException;

import android.content.SharedPreferences;
import android.preference.PreferenceManager;

public class GRSession {

	public static final int STATUS_ERR_MAX = 199;
	public static final int STATUS_ERR_MIN = 100;
	public static final int STATUS_ERR_WRONG_PASSWORD = 100;
	public static final int STATUS_ERR_NETWORK = 110;
	public static final int STATUS_ERR_TIMEOUT = 120;
	public static final int STATUS_ERR_INTERNAL = 130;

	public static final int STATUS_OK_MAX = 99;
	public static final int STATUS_OK_MIN = 2;
	public static final int STATUS_OK_ONLINE = 10;
	public static final int STATUS_OK_OFFLINE = 20;
	public static final int STATUS_OK_KEEP_OFFLINE = 30;

	private ARApplication app;
	
	private UserFactory userFactory;
	private MessageFactory messageFactory;

	public ARApplication getApp() {
		return app;
	}

	private String phpSessionID;

	/** UserID=Unique Number of the user in the whole lifetime */
	private String userID;

	/** Username */
	private String username;

	/**
	 * Password in ROT13-encoding
	 * */
	private String password;

	/**
	 * Preference-File for Andromeo
	 */
	public static final String PREFS_NAME = "MyPrefsFile";

	private String grurl = "http://www.gayromeo.com/";

	/**
	 * secureString will be filled by ARRequester and is used while viewing
	 * GR-User-Profiles as parameter
	 */
	private String secureString = "";

	public String getSecureString() {
		return secureString;
	}

	public void setSecureString(String secureString) {
		this.secureString = secureString;
	}

	private int status = -1;
	
	public int getStatus() {
		return status;
	}
	
	public void setStatus(int status) {
		this.status = status;
	}
	
	public GRSession(ARApplication pApp) {
		this.app = pApp;
		sessionCookie = new Vector<String>();
		userFactory = new UserFactory (this) {};
		messageFactory = new MessageFactory(this) {};
	}

	public final String getGrurl() {
		return grurl;
	}

	protected final void setGrurl(String grurl) {
		this.grurl = grurl;
	}

	/**
	 * @param userID
	 *            the userID to set
	 */
	public void setUserID(String userID) {
		this.userID = userID;
	}

	/**
	 * @return the userID
	 */
	public String getUserID() {
		return userID;
	}

	/**
	 * @param phpSessionID
	 *            the phpSessionID to set
	 */
	public void setPhpSessionID(String phpSessionID) {
		this.phpSessionID = phpSessionID;
	}

	/**
	 * @return the phpSessionID
	 */
	public String getPhpSessionID() {
		return phpSessionID;
	}

	/**
	 * @param username
	 *            the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param password
	 *            the password to set
	 */
	public void setPassword(String password) {
		this.password = ARUtil.encodeROT13(password);
		sessionStatus = STATUS_OK_OFFLINE;

	}

	/**
	 * 
	 * @return STATUS_CODE
	 */
	public int login() {

		// sessionStatus = ARUtil.login(this, password);
		try {

			ARUtil.writePHPSessionStringCookie(this);
			LoginProcessor.login(this, password);
			sessionStatus = STATUS_OK_ONLINE;

		} catch (ARException e) {

			e.printStackTrace();
			switch (e.andromeoException) {
			case ARException.AREXC_SESSION_TIMEOUT:
				sessionStatus = STATUS_ERR_TIMEOUT;

			case ARException.AREXC_WRONG_USER_PASSWORD:
				sessionStatus = STATUS_ERR_WRONG_PASSWORD;
				break;
			}

		} catch (UnsupportedEncodingException e) {

			e.printStackTrace();
			sessionStatus = STATUS_ERR_INTERNAL;

		} catch (ParserConfigurationException e) {

			e.printStackTrace();
			sessionStatus = STATUS_ERR_INTERNAL;

		} catch (SAXException e) {

			e.printStackTrace();
			sessionStatus = STATUS_ERR_INTERNAL;

		} catch (IOException e) {

			e.printStackTrace();
			sessionStatus = STATUS_ERR_NETWORK;

		}

		return sessionStatus;
	}

	private int sessionStatus = STATUS_OK_OFFLINE;

	public int getSessionStatus() {
		return sessionStatus;
	}

	public void setSessionStatus(int sessionStatus) {
		this.sessionStatus = sessionStatus;
	}

	private Vector<String> sessionCookie = null;

	public Vector<String> getSessionCookie() {
		if (sessionCookie == null)
			sessionCookie = new Vector<String>();
		return sessionCookie;
	}

	public void setSessionCookie(Vector<String> retrieveCookie) {
		// TODO Auto-generated method stub
		sessionCookie = retrieveCookie;
	}

	/**
	 * 
	 * @return true if LoginData were saved, false if not
	 */
	public boolean readLoginDataFromPrefs() {
		SharedPreferences settings;
		settings = PreferenceManager.getDefaultSharedPreferences(app);
		setUsername(settings.getString("savedUsername", ""));

		// write password directly preventing a rot13-conversion
		password = settings.getString("savedPassword", "");

		if (this.password == null) {
			return false;
		} else {
			return true;
		}
	}

	public boolean saveLoginDataToPrefs() {
		// TODO Auto-generated method stub

		SharedPreferences settings;
		// settings = app.getSharedPreferences(PREFS_NAME, 0);
		settings = PreferenceManager.getDefaultSharedPreferences(app);
		SharedPreferences.Editor editor = settings.edit();
		editor.putString("savedUsername", this.username);
		editor.putString("savedPassword", this.password);
		editor.commit();
		return true;
	}

	public void dropLoginData() {
		// TODO Auto-generated method stub
		SharedPreferences settings;
		// settings = app.getSharedPreferences(PREFS_NAME, 0);
		settings = PreferenceManager.getDefaultSharedPreferences(app);
		SharedPreferences.Editor editor = settings.edit();
		editor.remove("savedUsername");
		editor.remove("savedPassword");

		editor.commit();
	}

	public String getPassword() {
		return password;
	}

	public UserFactory getUserFactory() {
		return userFactory;
	}

	public void setUserFactory(UserFactory userFactory) {
		this.userFactory = userFactory;
	}

	public MessageFactory getMessageFactory() {
		return messageFactory;
	}

	public void setMessageFactory(MessageFactory messageFactory) {
		this.messageFactory = messageFactory;
	}

}
